Nuxt 3 提供兩個 composables(useFetch、useAsyncData)和一個 utils($fetch) 做為取得資料函式:
useFetch 最簡單最常用的函式$fetch 能根據使用者的行為發出請求useAsyncData 和 $fetch 一起使用,有更多的設定可以使用useFetch用 useFetch 測試昨天寫的 API。
在 app.vue 加入以下程式碼。
// app.vue
<template>
<div>
<div v-for="item in list.data">
{{ item.key.replaceAll('todo:', '') }}
<input type="checkbox" v-model="item.value.isFinish" @change="Put(item)">
<button type="button" @click="Delete(item)">Delete</button>
</div>
</div>
<label for="todo">todo:</label>
<input type="text" id="todo" name="todo" v-model="todo" />
<button type="button" @click="Post">Submit</button>
</template>
<script setup lang="ts">
const todo = ref('')
const list = ref([])
list.value = await useFetch('/api/todo')
const Post = async () => {
await useFetch('/api/todo', {
method: 'post',
body: { name: todo.value }
})
list.value = await useFetch('/api/todo')
}
const Put = async (item) => {
await useFetch('/api/todo', {
method: 'put',
body: { name: item.key.replaceAll('todo:', ''), isFinish:item.value.isFinish }
})
list.value = await useFetch('/api/todo')
}
const Delete = async (item) => {
await useFetch('/api/todo', {
method: 'delete',
body: { name: item.key.replaceAll('todo:', '')}
})
list.value = await useFetch('/api/todo')
}
</script>
畫面顯示:

測試功能:
新增


修改

刪除



useFetch 有提供一些設定透過參數可以控制其行為。
預設情況下,useFetch 在使用 Vue Suspense 導覽至新頁面前會等待其非同步函式解析,如果使用 lazy 選項就會忽略此功能。
<template>
<div v-if="pending">
...
</div>
<div v-else>
<div v-for="item in list">
...
</div>
</div>
</template>
<script setup lang="ts">
const { pending, data: list } = useFetch('/api/todo', {
lazy: true
})
</script>
也可以使用 useLazyFetch。
const { pending, data: list } = useLazyFetch('/api/todo')
預設情況下,useFetch 會在客戶端和伺服器環境上執行,將 server 設為 false 可以只在客戶端執行。
與 lazy 一起用對於第一次渲染時不需要的資料非常有用。
const { pending, data: list } = useFetch('/api/todo', {
lazy: true,
server: false
})
如果想要手動更新資料可以使用 refresh。
<template>
<div>
...
<button @click="refresh">Refresh data</button>
</div>
</template>
<script setup lang="ts">
const { data:list, error, execute, refresh } = await useFetch('/api/todo')
</script>
如果想要監聽某個值並更新資料可以使用 watch,可以監聽一個或多個元素。
const id = ref(1)
const { data:list, error, refresh } = await useFetch('/api/todo', {
watch: [id]
})
$fetch & useAsyncData$fetch 是 Nuxt 3 提供用來獲取資料的 Utils,讓我們不需要額外安裝套件即可進行 HTTP 請求。
在元件中直接使用 $fetch 會導致重複取得資料(SSR 時在伺服器端取得一次、Hydration 時再次取得),因為 $fetch 不會將狀態從伺服器傳遞到客戶端。
...
// 這邊會執行兩次
list.value = await $fetch('/api/todo')
...
為了避免在元件中重複取得資料的問題,官方文件明確建議使用 useFetch 或 useAsyncData + $fetch,這樣可以確保資料在伺服器端取得後能傳遞到客戶端。
...
list.value = await useAsyncData('todo', () => $fetch('/api/todo'))
...
也可以在客戶端的事件裡直接使用 fetch
// app.vue
<template>
...
<button type="button" @click="Post">Submit</button>
</template>
<script setup lang="ts">
...
const Post = async () => {
await $fetch('/api/todo', {
method: 'post',
body: { name: todo.value }
})
}
...
</script>
以開發的角度來說使用 useFetch 較為方便,不管什麼情況 useFetch 都有相對應的設定,反而 $fetch 和 useAsyncData 在使用上有許多要注意的地方,一不小心可能就會踩到雷。
這幾天介紹了 Server API 的使用方式及取得資料的方法,明天會介紹用於轉場的效果 Transitions 。
Data fetching
useFetch
useAsyncData
fetch